﻿using Microsoft.AspNetCore.SignalR.Client;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Linq;
using static System.Net.Mime.MediaTypeNames;

namespace CJSignalR
{
    public partial class Form1 : Form
    {
        HubConnection connection;                          //hub
        FileSystemWatcher watcher;                         //文件监控
        SerialPort serialPort;                             //串口


        #region SignalR配置
        public string enterNo { get; set; }                //企业代号
        public string terminalName { get; set; }           //终端名称
        public string signalRIP { get; set; }              //signalR地址
        public string signalRConnectId { get; set; }       //客户端ID

        #endregion

        public Form1()
        {
            InitializeComponent();
            //文件
            this.watcher = new FileSystemWatcher();

            this.watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.DirectoryName;
            this.watcher.IncludeSubdirectories = true;
            this.watcher.Created += new FileSystemEventHandler(FileWatcher_Created);


            //串口

            this.serialPort = new SerialPort();


            ////signalr

            //new HubConnectionBuilder()
            //.WithUrl(new Uri("http://127.0.0.1:5000/chathub"))
            //.WithAutomaticReconnect()
            //.Build();

            //connection.Closed += async (error) =>
            //{
            //    await Task.Delay(new Random().Next(0, 5) * 1000);
            //    await connection.StartAsync();
            //};
        }

        private async void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                System.Threading.Thread.Sleep(500);
                string txt = serialPort.ReadExisting();
                if (txt != null)
                {
                    //发送串口数据
                    await connection.InvokeAsync("RS232DataCommunicate", new List<string>() { signalRConnectId }, txt);

                    try
                    {

                        this.dataGridView1.Invoke(new Action(() =>
                        {

                            int index = this.dataGridView1.Rows.Add();
                            this.dataGridView1.Rows[index].Cells[0].Value = "串口";
                            this.dataGridView1.Rows[index].Cells[1].Value = DateTime.Now.ToString();
                            this.dataGridView1.Rows[index].Cells[2].Value = "发送:" + txt;

                        }));
                        //插入记录

                    }
                    catch
                    {

                    }
                    LogHelper.SaveNote("串口发送数据：" + txt);

                }
            }
            catch (Exception ex)
            {
                LogHelper.SaveNote("串口异常：" + ex.Message);
            }
        }

        protected async void FileWatcher_Created(object sender, FileSystemEventArgs e)
        {
            Console.WriteLine("新增:" + e.ChangeType + ";" + e.FullPath + ";" + e.Name);

            string hz = Path.GetExtension(e.Name);
            string content = "";
            if (hz == ".txt")
            {
                content = File.ReadAllText(e.FullPath, Encoding.UTF8);
            }
            else if (hz == ",xls" || hz == ",xlsx" || hz == ".csv")
            {

            }
            else
            {

            }

            await connection.InvokeAsync("TxtDataCommunicate", signalRConnectId, content, hz);  //发送文件内容


        }
        private async void ReceiveBtn_Click(object sender, EventArgs e)
        {
            connection.On<int, string>("ReceiveMessage", (status, message) =>
            {

                this.Invoke(new Action(() =>
                {
                    if (status == 1)// 文件
                    {
                        this.watcher.Path = message;
                        this.watcher.EnableRaisingEvents = true;
                    }
                    else if (status == 2) //串口
                    {
                        if (this.serialPort.IsOpen)
                        {
                            Console.WriteLine("error~ port is open!");
                        }
                        else
                        {
                            try
                            {
                                JObject obj = JObject.Parse(message);
                                this.serialPort.BaudRate = (int)obj["BaudRate"];
                                this.serialPort.DataBits = (int)obj["DataBits"];
                                this.serialPort.Parity = (Parity)(int)obj["Parity"];
                                this.serialPort.StopBits = (StopBits)(int)obj["StopBits"];
                                this.serialPort.PortName = obj["PortName"].ToString();
                                this.serialPort.Open();
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(ex.Message);
                            }
                        }


                    }
                    else
                    {

                    }
                }
                ));

            });

            try
            {
                await connection.StartAsync();


            }
            catch (Exception ex)
            {

            }
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            LinkConfig linkConfig = new LinkConfig(this);
            linkConfig.Show();
        }

        /// <summary>
        /// 设置连接配置
        /// </summary>
        public async void SetLinkConfig(string _enterNo, string _terminalName, string _signalRIP)
        {
            lblEnterNo.Text = _enterNo;
            lblTerminalName.Text = _terminalName;
            lblSignalRIP.Text = _signalRIP;

            enterNo = _enterNo;
            terminalName = _terminalName;
            signalRIP = _signalRIP;


            //设置完成后进行SignalR的连接
            connection = new HubConnectionBuilder()
            .WithUrl(new Uri(signalRIP))
            .WithAutomaticReconnect()
            .Build();

            //连接
            connection.On<string>("onServiceConnect", (connectId) =>
            {

                lblConnectID.Text = connectId;
            });
            //获取串口号
            connection.On<string>("onSetTerminalPortNames", (connectId) =>
            {
                signalRCID.Text = connectId;
                signalRConnectId = connectId;
                connection.InvokeAsync("SetTerminalPortNames", new List<string>() { connectId }, SerialPort.GetPortNames().ToList());
            });
            //获取串口波特率、停止位等信息，然后连接，给服务器是否连接成功标记
            connection.On<string, string, string, string, string, string>("onLinkRS232Terminal", (connectId, portName, baudRate, dataBits, stopBits, parity) =>
            {
                signalRConnectId = connectId;
                if (!this.serialPort.IsOpen)
                {
                    this.serialPort.BaudRate = Convert.ToInt32(baudRate);
                    this.serialPort.DataBits = Convert.ToInt32(dataBits);
                    this.serialPort.Parity = (Parity)Convert.ToInt32(parity);
                    this.serialPort.StopBits = (StopBits)Convert.ToInt32(stopBits);
                    this.serialPort.PortName = portName;

                    this.serialPort.RtsEnable = true;
                    this.serialPort.DtrEnable = true;
                    this.serialPort.DataReceived += SerialPort_DataReceived;
                    this.serialPort.Open(); //打开串口

                }
                //串口是否打开成功
                connection.InvokeAsync("CallBackLinkRS232Terminal", new List<string>() { connectId }, this.serialPort.IsOpen);
            });

            //断开串口
            connection.On<string>("onStopRS232Terminal", (connectId) =>
            {
                lblConnectID.Text = "";
                this.serialPort.Close();
                connection.InvokeAsync("CallBackLinkRS232Terminal", new List<string>() { connectId }, this.serialPort.IsOpen);
            });

            Connect();


        }

        //连接
        private async void Connect()
        {
            try
            {
                await connection.StartAsync().ContinueWith(async (t) =>
                {
                    if (!t.IsFaulted)
                    {
                        pictureBox1.Image = CJSignalR.Properties.Resources.dot;
                        //连接服务器
                        await connection.InvokeAsync("ServiceConnect", enterNo, terminalName, signalRConnectId);

                    }
                    else
                    {
                        pictureBox1.Image = CJSignalR.Properties.Resources.dot__1_;

                        lblConnectID.Text = "";
                        this.serialPort.Close();
                        // await connection.InvokeAsync("CallBackLinkRS232Terminal", signalRConnectId, this.serialPort.IsOpen);

                        System.Threading.Thread.Sleep(5000);
                        Connect();
                    }
                });

            }
            catch (Exception ex) //报错重连
            {
                System.Threading.Thread.Sleep(5000);
                Connect();
            }
        }

        private void toolStripButton2_Click(object sender, EventArgs e) //打开日志文件夹
        {
            var psi = new System.Diagnostics.ProcessStartInfo() { FileName = LogHelper.GetLogDirectory("LogDirectory"), UseShellExecute = true };
            System.Diagnostics.Process.Start(psi);


        }



    }
}
